package com.kd.crawler.dao.crawler;

import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.kd.crawler.dao.BaseDao;
import com.kd.crawler.entity.CrawlerEntry;

public class CrawlerEntryDao extends BaseDao {
	
	private static CrawlerEntryDao instance;
	
	public static CrawlerEntryDao getInstance() {
		if(instance==null){
			synchronized(CrawlerEntryDao.class) {
				if(instance==null) {
					instance=new CrawlerEntryDao();
				}
			}
		}
		return instance;
	}
	
	/**
	 * query some entry url from a start index to queue of JMS
	 * get all of outside url
	 * @param start, start index to select
	 * @param limit, number
	 * @return
	 */
	public List<CrawlerEntry> queryOutside(int start,int limit){
//		String sql = "select entryId entryId, entryUrl url, lastExecuteDate lastExecutedDate, typeId typeId, intervalTime intervalTime from entrytable where entryId> ? order by entryID LIMIT ?";
		String sql = "select "
				+ "et.entryId,"
				+ "et.jobID,"
				+ "j.level, "
				+ "j.regionId, "
				+ "et.entryUrl url, "
				+ "et.lastExecuteDate lastExecutedDate, "
				+ "et.typeId typeId,"
				+ " et.intervalTime intervalTime, " +
				" j.AnalyseClass parserName " +
				" from entrytable et left join job j on et.jobID=j.id " +
				" where entryId>? and et.status=0 AND et.typeid IN (0,7,8,10) AND et.lastExecuteDate<=(UNIX_TIMESTAMP()-et.intervalTime) order by entryID LIMIT ? "; 
//		System.out.println(sql);
		return this.query(sql, CrawlerEntry.class, start, limit);
	}
	
	/**
	 * initialize entry url dictionary to judge a url is detailed url or not.
	 * get all of inside url.
	 * @param start
	 * @param limit
	 * @return
	 */
	public List<CrawlerEntry> queryInside(int start, int limit) {
		String sql = "select "
				+ "et.entryId,"
				+ "et.jobID,"
				+ "j.level, "
				+ "j.regionId, "
				+ "et.entryUrl url, "
				+ "et.lastExecuteDate lastExecutedDate, "
				+ "et.typeId typeId,"
				+ " et.intervalTime intervalTime, " +
				" et.AnalyseClass parserName " +
				" from entrytable et left join job j on et.jobID=j.id " +
				" where entryId>? and et.status=0 AND et.typeid IN (1, 3, 11) AND et.lastExecuteDate<=(UNIX_TIMESTAMP()-et.intervalTime) order by entryID LIMIT ? ";
		return this.query(sql, CrawlerEntry.class, start, limit);
	}
	
	/**
	 * use to test
	 * @param entryId
	 * @return
	 */
	public CrawlerEntry query(int entryId) {
		String sql = "select et.entryId entryId, et.entryUrl url, et.lastExecuteDate lastExecutedDate, et.typeId typeId, et.intervalTime intervalTime, " +
				" j.AnalyseClass parserName " +
				" from entrytable et left join job j on et.jobID=j.id " +
				" where entryId=? and et.status=0 "; 
		List<CrawlerEntry> cus = this.query(sql, CrawlerEntry.class, entryId);
		if(null==cus || 0==cus.size()) {
			return null;
		}
		return cus.get(0);
	}
	
	public int insert(CrawlerEntry ce) {
		String sql  = "insert into tb_original_html(entry_id, job_id, parser_name, url, html_text, status_code, is_parsed, create_time) values(?, ?, ?, ?, ?, ?, ?, now())";
		try {
			String html = ce.getHtml();
			if(StringUtils.isNotBlank(html) && html.length()>65535) {
				html = html.substring(0, 65535);
			}
			return this.update(sql, ce.getEntryId(), ce.getJobID(), ce.getParserName(), ce.getUrl(), ce.getHtml(), ce.getStatusCode(), "N");
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
	}
	
	/**
	 * update lastest crawling time and status to renew crawl work, when it finishes crawling.
	 * @param lastExecutedTime
	 * @param status
	 * @param entryId
	 * @return
	 */
	public int update(long lastExecutedTime, int entryId) {
		String sql = "update entrytable set lastExecuteDate=?, status=0 where entryID=?";
		return this.update(sql, lastExecutedTime, entryId);
	}
	
	/**
	 * update status related with entry url, when it has come into the specified queue of JMS
	 * @param entryId
	 * @param status
	 * @return
	 */
	public int update(boolean status, int entryId) {
		String sql = "update entrytable set status=? where entryID=?";
		if(status) {
			return this.update(sql, 1, entryId);
		} else {
			return this.update(sql, 0, entryId);
		}
	}
	
	public static void main(String[] args) {
		List<CrawlerEntry> list=CrawlerEntryDao.getInstance().queryInside(0, 1);
		System.out.println(list.get(0));
	}
}
